package client.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.rmi.PortableRemoteObject;

import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;

import client.ParticipantUser;
import client.RemoteParticipant;
import client._RemoteParticipant_Stub;

public class ParticipantUserImpl implements ParticipantUser {
	private String name;
	private POA poa;
	private ORB orb;
	private String listening_address;
	private int listening_port;
	private RemoteParticipant participant = null;
	private boolean isRefresh = false;

	public ParticipantUserImpl(String name) {
		this.name = name;
		orb = ORB.init(new String[] {}, null);
		new Thread(new Runnable() {
			public void run() {
				orb.run();
			}
		}).start();

		try {
			poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
			poa.the_POAManager().activate();

		} catch (Exception e) {
			System.out
					.println("EmbededObjectImpl : erreur d'activation du poa !!!");
			return;
		}
	}

	public String getParticipantName() throws RemoteException {
		return name;
	}

	public boolean beginUsing(String topicFullName) throws RemoteException {
		try {
			// servant
			_ParticipantUserImpl_Tie tie = new _ParticipantUserImpl_Tie();
			tie.setTarget(this);

			org.omg.CORBA.Object objet = poa.servant_to_reference(tie);
			String ior = orb.object_to_string(objet);

			loadProperties();
			InetAddress group = InetAddress.getByName(listening_address);
			DatagramSocket socket = new DatagramSocket();
			DatagramPacket writter = new DatagramPacket(ior.getBytes(),
					ior.getBytes().length, group, listening_port);
			socket.send(writter);
			socket.close();

			ServerSocket server = new ServerSocket(listening_port);
			Socket soc = server.accept();
			BufferedReader br = new BufferedReader(new InputStreamReader(
					soc.getInputStream()));
			String iorSender = br.readLine();
			server.close();
			
			if(iorSender.equals("null"))
				return false;

			org.omg.CORBA.Object obj = orb.string_to_object(iorSender);
			participant = (RemoteParticipant) PortableRemoteObject
					.narrow(obj, RemoteParticipant.class);
			br.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private boolean loadProperties() {
		Properties prop = new Properties();
		String path = new File(".").getAbsolutePath();
		path = path.substring(0, path.length() - 1);
		try {
			prop.load(new FileInputStream(path
					+ "conf\\client_properties.properties"));
			listening_port = Integer.parseInt(prop
					.getProperty("PARTICIPANT_LISTENING_PORT"));
			listening_address = prop
					.getProperty("PARTICIPANT_LISTENING_ADDRESS");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public void setData(Object data) throws RemoteException {
		participant.setData(data);
	}

	public Object getData() throws RemoteException {
		return participant.getData();
	}

	public void endUsing(String topicFullName) throws RemoteException {
		participant.endUsing(topicFullName);
	}
	
	public void refresh() throws RemoteException{
		isRefresh = true;
	}

	public boolean isRefresh() {
		return isRefresh;
	}

	public void setRefresh(boolean isRefresh) {
		this.isRefresh = isRefresh;
	}

}
